/**
 * Created by tianling on 2016/12/25.
 */
module.exports = class {
    constructor() {
        this.key = "iframe:orgstruct";
    }

    static init() {
        return new this();
    }

    /**
     * 获取系统模块列表
     */
    async getOrgStructItemsByDB() {
        return await global.DataBase.iframe_orgstruct.Access.findAll({
            where: {
                OS_IsDel: 0
                //OS_IsShow:1
            },
            order: ['OS_Sort'],
            raw: true
        })
    };

    /**
     *
     * @param {*} partnerId 合作伙伴ID
     */
    async getOrgStructItems(partnerId) {
        if (partnerId == undefined || partnerId == null || partnerId === 0 || partnerId === "0") {
            if (!global.Config.isShareMemory) {
                return global.iframe_orgstruct["all"];
            } else {
                let redisClient = global.Redis.getClient();
                let ret = await redisClient.get(this.key + ":all");
                return JSON.parse(ret);
            }

        } else {
            if (!global.Config.isShareMemory) {
                let ret = global.iframe_orgstruct[partnerId];
                if (!ret) {
                    ret = [];
                }
                return ret;
            } else {
                let redisClient = global.Redis.getClient();
                let ret = await redisClient.get(this.key + ":" + partnerId);
                return JSON.parse(ret);
            }


        }
    }

    async Sync() {
        let getChildrens = function (Items, pid) {
            let cdata = [];
            for (let i = 0; i < Items.length; i++) {
                let item = Items[i];
                if (item.OS_ParentID == pid) {
                    cdata.push(item);
                    cdata = cdata.concat(getChildrens(Items, item.OS_ID))
                }
            }
            return cdata;
        };

        let ret = {};
        let orgstruct = await this.getOrgStructItemsByDB();
        let partners = orgstruct.filter(item => {
            return item.OS_Type === '001';
        });

        for (let item of partners) {
            ret[item.OS_ID] = getChildrens(orgstruct, item.OS_ID);
            ret[item.OS_ID].splice(0, 0, item);
        }
        ret["all"] = orgstruct;
        if (!global.Config.isShareMemory) {
            global.iframe_orgstruct = ret;
        } else {
            let redisClient = global.Redis.getClient();
            let pipeline = redisClient.pipeline();
            for (let key in ret) {
                pipeline.set(this.key + ":" + key, JSON.stringify(ret[key]));
            }
            await pipeline.exec();
        }
        log.info("加载组织结构成功");
        return true;
    }




    /**
     * 获取某个键值对
     * @param {*} ID
     */
    async GetOrgStuctItem(ID) {
        let Items = await this.getOrgStructItems();
        let _items = Items.filter(function (item) {
            if (item && item.OS_ID == ID) return true;
        });
        if (_items.length > 0) return _items[0];

        return null;
    }


    /**获取所有的父级ID**/
    async GetParentsID(ChildrenID) {
        let Parents = [];
        let item = await this.GetOrgStuctItem(ChildrenID);
        if (item) {
            Parents.push(item.OS_ID);
            Parents = Parents.concat(this.GetParentsID(item.OS_ParentID));
        }
        return Parents;
    };

    /**
     * 获取所有父级的名称
     * @param {String} ChildrenID
     */
    async GetParentsName(ChildrenID) {
        let Parents = [];
        let item = await this.GetOrgStuctItem(ChildrenID);
        if (item) {
            Parents.push(item.OS_Name);
            Parents = Parents.concat(await this.GetParentsName(item.OS_ParentID));
        }
        return Parents;
    };


    /**获取所有的父级模型**/
    async GetParentsModel(ChildrenID) {
        let Parents = [];
        let item = await this.GetOrgStuctItem(ChildrenID);
        if (item) {
            Parents.push(item);
            Parents = Parents.concat(await this.GetParentsModel(item.OS_ParentID));
        }
        return Parents;
    };

    /**
     * 根据 OS_Type 查找指定类型的父级 用于从下向上查找
     * @param {NUmber} ChildrenID
     * @param {String} Type
     */
    async GetParentModelByType(ChildrenID, Type) {
        let item = await this.GetOrgStuctItem(ChildrenID);
        if (item) {
            if (item.OS_Type === Type) {
                return item;
            } else {
                return await this.GetParentModelByType(item.OS_ParentID, Type);
            }
        }
        return null;
    };


    /**
     * 从上到下 获取指定类型的子集
     * @param {Number} PartnersId 合作伙伴ID
     * @param {Number} ParentID
     * @param {String} Type
     */
    async GetChildrensModelByType(PartnersId, ParentID, Type) {
        let self = this;
        let Childrens = [];
        let Items = await this.GetModelsByType(PartnersId, ParentID, Type);
        Items.map(async (item) => {
            Childrens = Childrens.concat(await self.GetParentsModel(item.OS_ID));
        });
        return Childrens;
    }



    /**
     * 根据Type获取记录 忽略上下级关系
     * @param {Number} PartnersId 合作伙伴ID
     * @param {Number} ParentID 可为null，为null时查找所有记录，ParentID存在时，查找当前父级下所有符合条件的子集
     * @param {String} Type
     */
    async GetModelsByType(PartnersId, ParentID, Type) {
        let Items = [];
        if (ParentID) {
            Items = await this.getChildrensModel(PartnersId, ParentID);
            Items.push(await this.GetOrgStuctItem(ParentID));
        } else {
            Items = await this.getOrgStructItems(PartnersId);
        }
        let _items = Items;
        if (Type && Type !== '') {
            _items = Items.filter(function (item) {
                return item.OS_Type === Type;
            });
        }
        return _items;
    }

    async getChildrensID(ParentID) {
        let Childrens = [];
        let Items = await this.getOrgStructItems();
        for (let i = 0; i < Items.length; i++) {
            let item = Items[i];
            if (item.OS_ParentID == ParentID) {
                Childrens.push(item.OS_ID);
                Childrens = Childrens.concat(await this.getChildrensID(item.OS_ID));
            }
        }
        return Childrens;
    }

    async getChildrensModel(partnersId, ParentID) {
        let Childrens = [];

        let Items = await this.getOrgStructItems(partnersId);
        for (let i = 0; i < Items.length; i++) {
            let item = Items[i];
            if (item.OS_ParentID === ParentID) {
                Childrens.push(item);
                Childrens = Childrens.concat(await this.getChildrensModel(partnersId, item.OS_ID));
            }
        }
        return Childrens;
    }

    /**
     *
     * @param {*} PartnersID 合作伙伴ID
     * @param {*} Name
     */
    async GetOrgStructItemByName(PartnersID, Name) {

        let Items = await this.getOrgStructItems(PartnersID);
        let _items = Items.filter(function (item) {
            if (item.OS_Name === Name) return true;
        });
        if (_items.length > 0) return _items[0];
        return null;
    };

    /**
     * 根据各自的数据可视化程度 获取用户可见的组织结构
     * @param moduleId 模块ID 前端返回 当前页面的模块ID 存在于每个请求的头部 req.headers.moduleid
     * @param userInfo 用户信息
     * @returns {Promise<*>}
     * @constructor
     */
    async GetUserOrgStructItems(moduleId, userInfo) {
        let ret = {};
        let degree = require('./data-degree').init();
        let FindFilter = await degree.getDegree(moduleId, userInfo, {
            orgId: 'OS_ID'
        });
        FindFilter.OS_IsDel = 0;
        // FindFilter.OS_IsShow=1;
        ret = await global.DataBase.iframe_orgstruct.Access.findAll({
            where: FindFilter,
            order: [
                ['OS_Sort', 'asc']
            ],
            raw: true
        });

        return ret;
    }


    /**
     * 根据各自的数据可视化程度 获取用户可见的组织结构的树形结构数据
     * @param moduleId 模块ID 前端返回 当前页面的模块ID 存在于每个请求的头部 req.headers.moduleid
     * @param userInfo 用户信息
     * @returns {Promise<*>}
     * @constructor
     */
    async GetUserOrgStructTreeData(moduleId, userInfo) {
        let item = await this.GetUserOrgStructItems(moduleId, userInfo);
        return this.GetTreeData(0, userInfo.UserPartnersID, item);
    }

    /**
     * 根据各自的数据可视化程度 获取用户可见的企业列表
     * @param moduleId
     * @param userInfo
     * @returns {Promise<Array<Model>>}
     */
    async getPartnersItems(moduleId, userInfo) {
        let ret = {};
        let degree = require('./data-degree').init();
        let FindFilter = await degree.getDegree(moduleId, userInfo, {
            orgId: 'OS_ID'
        });
        FindFilter.OS_IsDel = 0;
        FindFilter.OS_Type = '001';
        // FindFilter.OS_IsShow=1;
        ret = await global.DataBase.iframe_orgstruct.Access.findAll({
            where: FindFilter,
            order: [
                ['OS_Sort', 'asc']
            ],
            raw: true
        });
        for (let item of ret) {
            let parent = await this.GetParentModelByType(item.OS_ParentID, '001');
            if (parent) {
                item.OS_ParentID = parent.OS_ID;
            }
        }
        return ret;
    }


    /**
     * 根据各自的数据可视程度 获取用户可见的组织结构的树形结构数据
     * @param moduleId
     * @param userInfo
     * @returns {Promise<Array>}
     */
    async getPartnersItemsTreeData(moduleId, userInfo) {
        let items = await this.getPartnersItems(moduleId, userInfo);
        return this.GetTreeData(0, userInfo.UserPartnersID, items);
    }

    /**
     *
     * @param PartnersID
     * @param ParentID
     * @param Items
     * @returns {Array}
     * @constructor
     */
    async GetTreeData(PartnersID, ParentID, Items) {
        //if(PartnersID<0) PartnersID=0;
        if (!Items) {
            Items = await this.getOrgStructItems(PartnersID);
        }
        if (!Items || Items.length === 0) {
            return [];
        }

        let data = [];
        let getChildrens = function (pid) {
            let cdata = [];
            for (let i = 0; i < Items.length; i++) {
                let item = Items[i];
                if (item.OS_ParentID === pid) {
                    let data_item = {
                        title: item.OS_Name,
                        value: item.OS_ID,
                        key: item.OS_ID,
                        children: getChildrens(item.OS_ID)
                    };
                    //if(data_item.children.length==0) delete data_item.children;
                    cdata.push(data_item);
                }
            }
            return cdata;
        };

        if (ParentID > 0) {
            let curP = await this.GetOrgStuctItem(ParentID);
            data.push({
                title: curP.OS_Name,
                value: curP.OS_ID,
                key: curP.OS_ID,
                children: getChildrens(curP.OS_ID)
            })
        } else {
            // if(ParentID===-1){
            //     data.push({
            //         title: '平台',
            //         value: -1,
            //         key: -1,
            //         children: getChildrens(0)
            //     });
            // }else{
            //     data = getChildrens(0);
            // }
            data = getChildrens(0);

        }

        return data;
    }


};